package service

import (
	"context"
	v1 "user/api/comment/v1"
	"user/internal/data"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

// CommentService 提供评论相关的业务接口，实现 v1.CommentServer
type CommentService struct {
	repo *data.CommentRepo
	v1.UnimplementedCommentServiceServer
}

// NewCommentService 构造函数，供 wire 注入
func NewCommentService(repo *data.CommentRepo) *CommentService {
	return &CommentService{repo: repo}
}

// AddComment 新增评论
func (s *CommentService) AddComment(ctx context.Context, req *v1.AddCommentRequest) (*v1.AddCommentReply, error) {
	c := &data.Comment{
		ArticleID: req.ArticleId,
		ParentID:  req.ParentId,
		UserID:    req.UserId,
		Content:   req.Content,
	}
	inserted, err := s.repo.AddComment(ctx, c)
	if err != nil {
		return &v1.AddCommentReply{Code: 500, Msg: err.Error()}, nil
	}
	return &v1.AddCommentReply{
		Code:    0,
		Msg:     "ok",
		Comment: ToProtoComment(inserted),
	}, nil
}

// GetCommentTree 获取评论树，分页返回顶级评论及其子树
func (s *CommentService) GetCommentTree(ctx context.Context, req *v1.GetCommentTreeRequest) (*v1.GetCommentTreeReply, error) {
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}
	roots, total, err := s.repo.GetCommentsTree(ctx, req.ArticleId, req.Page, req.PageSize)
	if err != nil {
		return &v1.GetCommentTreeReply{Code: 500, Msg: err.Error()}, nil
	}
	return &v1.GetCommentTreeReply{
		Code:     0,
		Msg:      "ok",
		Comments: ToProtoCommentList(roots),
		Total:    total,
	}, nil
}

// ToProtoComment 将 data.Comment 转为 proto.Comment
func ToProtoComment(c *data.Comment) *v1.Comment {
	if c == nil {
		return nil
	}
	children := make([]*v1.Comment, 0, len(c.Children))
	for _, child := range c.Children {
		children = append(children, ToProtoComment(child))
	}
	id := ""
	if c.ID != primitive.NilObjectID {
		id = c.ID.Hex()
	}
	return &v1.Comment{
		Id:         id,
		ArticleId:  c.ArticleID,
		ParentId:   c.ParentID,
		UserId:     c.UserID,
		Content:    c.Content,
		CreatedAt:  c.CreatedAt,
		LikeCount:  c.LikeCount,
		ReplyCount: c.ReplyCount,
		Children:   children,
	}
}

// ToProtoCommentList 批量转换
func ToProtoCommentList(list []*data.Comment) []*v1.Comment {
	out := make([]*v1.Comment, 0, len(list))
	for _, c := range list {
		out = append(out, ToProtoComment(c))
	}
	return out
}
